// 模拟 bind 实现

Function.prototype.bind1 = function () {
    // 对传入的值做处理
    let args = Array.prototype.slice.call(arguments)

    // self 就是 fn1.bind1(...) 中 fn1 的 this
    let self = this
    // 获取数组第一项
    let one = args.shift()
    // 作为一个函数进行返回
    return function () {
        return self.apply(one, args)
    }
}

function fn1(a, b) {
    console.log('this', this)
    console.log(a, b)
    return 'this is fn1'
}

const fn2 = fn1.bind1({
    x: 100
}, 10, 20)
const res = fn2()
console.log(res)


// 模拟实现bind
Function.prototype.bind1 = function () {
    // 处理传参变为数组
    let args = Array.prototype.slice.call(arguments)
    // 获得第一个数组的值，传入的参数
    let one = args.shift()
    // 此时的this表示需要改变this的函数，并赋值给self
    let self = this
    // 返回一个函数，改变函数的指向，指向第一个参数
    return function () {
        return self.apply(one, args)
    }
}

// 手写bind函数
Function.prototype.bind1 = function () {
    // 转化成数组
    let args = Array.prototype.slice.call(arguments)
    // 处理数组第一项
    let t = args.shift()
    let self = this
    // 返回一个函数
    return function () {
        return self.apply(t, args)
    }
}

// 手写深拷贝
function deepClone(obj) {
    if (typeof obj !== 'object' || typeof obj === null) {
        return obj
    }
    let result = obj instanceof Array ? [] : {}
    for (let key in obj) {
        if (obj.hasOwnPorperty(key)) {
            result[key] = typeof obj[key] === 'object' ? deepClone(obj[key]) : obj[key]
        }
    }
    return result
}

// 浅拷贝
//  拷贝数组等 1. concat , 2. slice 
let arr = [1, 2, 3, 4]
let nArr = arr.concat()
let nArr1 = arr.slice()


// 对象， 数组的深拷贝
const nArr2 = JSON.parse(JSON.stringify(arr))


// 手写bind函数
Function.prototype.bind1 = function () {
    // 转化数组
    // let args =   Array.prototype.slice.call(arguments)
    let args =  Array.of(arguments)
    // 获取第一项
    const t = args.shift()
    let self = this
    return function () {
        return self.apply(t, args)
    }
}

// 手写深拷贝
function deepClone(obj) {
    if (typeof obj !== 'object' || obj == null) {
        return obj
    }
    // 声明一个 result
    let result = obj instanceof Array ? [] : {}
    // 循环obj
    for (let key in obj) {
        if (obj.hasOwnProperty(key)) {
            result[key] = typeof obj[key] === 'object' ? deepClone(obj[key]) : obj[key]
        }
    }
    return result
}

// 手写 节流 时间够勒才执行下一次
    function throttle (fn,wait) {
        var timeout
        return function () {
            var context = this
            var args =  arguments
            if(!timeout) {
                timeout = setTimeout(function () {
                    fn.apply(context,args)
                   timeout = null
                },wait)
            }
        }
    }

    // 防抖
    function debounce(fn,wait) {
        var timeout
        return function() {
            let args = arguments
            clearTimeout(timeout)
            timeout = setTimeout(()=> {
                fn.apply(this,args)
            },wait)
        }
    }

  function deepClone(obj) {
      let newObj = obj instanceof Array ? [] : {}
      if (obj == null || typeof obj !== 'object') {
        return obj
      }
      for (let key in obj) {
          if (obj.hasOwnPorperty(key)) {
            newObj[key] = typeof obj[key] === 'object' ? deepClone(obj[key]) : obj[key]
          }
      }
      return newObj
  }

 function deepClone(obj) {
     if (typeof obj !== 'object' || obj == null) {
         return obj
     }
     let result = obj instanceof Array.prototype ? [] : []
     for (let key in obj) {
        if (obj.hasOwnProperty(key)) {
            result[key] = typeof obj[key] !== 'object' ? obj[key] : deepClone(obj[key])
        }
     }
     return result
 }

 